﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using BL;
using MyExceptions;
using System.Collections.ObjectModel;
using DataModels;

namespace HouseKeepingServices
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class Services : IServices
    {

        private static readonly BLClass bl = new BLClass();

        public int GetInt()
        {
            return 444;
        }
        public String GetString()
        {
            return "muhahahahaa";
        }

        public User GetUser(string username)
        {
            User user = bl.GetUser(username);
            if (user != null)
            {
                return new User()
                {
                    Id = user.Id,
                    Username = user.Username,
                    Password = user.Password,
                    UserTypeId = user.UserTypeId
                };
            }
            return null;
        }

        public User GetUserData(string username)
        {
            User user = bl.GetUserData(username);
            if (user == null)
                return null;


            return new User ()
            {
                Id = user.Id,
                Username = user.Username,
                Password = user.Password,
                UserTypeId = user.UserTypeId,
                Incomes1 = GetIncomesForUsers(username),
                Outcomes1 =  GetOutcomesForUsers(username)
            };
        }

        public bool IsUsernameTaken(string username)
        {
            return bl.IsUsernameTaken(username);

        }

        /// <summary>
        /// checks wheter the user is authenticated or not
        /// </summary>
        /// <param name="username">typed username</param>
        /// <param name="password">typed password</param>
        /// <returns>true if auth, false otherwise</returns>
        public bool IsUserAuthenticated(string username, string password)
        {
            try
            {
                return bl.IsUserAuthenticated(username, password);
            }
            catch (Exception ex)
            {
                
                throw ex;
            }
        }
        public bool InsertUser(User user)
        {
            return bl.InsertUser(user);
        }


        public DataTypeBulk GetDataTypes()
        {
            return new DataTypeBulk()
            {
                ActionIncomeTypesData =  GetIncomeActionTypes(),
                ActionOutcomeTypesData = GetOutcomeActionTypes(),
                UserTypesData  = GetUserTypes(),
                ReportTypesData = GetReportTypesAvailable()

            };
        }

        public ObservableCollection<ReportType> GetReportTypesAvailable()
        {
            return bl.GetReportTypesAvailable();
        }
        
        public ObservableCollection<ActionType> GetActionTypes()
        {
            ObservableCollection<ActionType> tempOC = bl.GetActionTypes();
            ObservableCollection<ActionType> oc = new ObservableCollection<ActionType>();
            foreach (var item in tempOC)
            {
                oc.Add(new ActionType()
                {
                    Id = item.Id,
                    Type = item.Type,
                    Kind = item.Kind
                });
            }

            return oc;
        }
        public ObservableCollection<ActionType> GetOutcomeActionTypes()
        {
            ObservableCollection<ActionType> tempOC = bl.GetOutcomeActionTypes();
            ObservableCollection<ActionType> oc = new ObservableCollection<ActionType>();
            foreach (var item in tempOC)
            {
                oc.Add(new ActionType()
                {
                    Id = item.Id,
                    Type = item.Type,
                    Kind = item.Kind
                });
            }

            return oc;
        }
        public ObservableCollection<ActionType> GetIncomeActionTypes()
        {
            ObservableCollection<ActionType> tempOC = bl.GetIncomeActionTypes();
            ObservableCollection<ActionType> oc = new ObservableCollection<ActionType>();
            foreach (var item in tempOC)
            {
                oc.Add(new ActionType()
                {
                    Id = item.Id,
                    Type = item.Type,
                    Kind = item.Kind
                });
            }

            return oc;
        }

        public ObservableCollection<UserType> GetUserTypes()
        {
            ObservableCollection<UserType> tempOC = bl.GetUserTypes();
            ObservableCollection<UserType> oc = new ObservableCollection<UserType>();
            foreach (var item in tempOC)
            {
                oc.Add( new UserType()
                {
                    Id = item.Id,
                    Type = item.Type
                });
            }

            return oc;
        }

        public void UpdateUser(User user)
        {
            bl.UpdateUser(user);
        }

        public void DeleteUserByID(int userID)
        {
            bl.DeleteUserByID(userID);
        }

        public void DeleteUserByUsername(string Username)
        {
            bl.DeleteUserByUsername(Username);
        }

        public ObservableCollection<Income> GetIncomesForUsers(String user)
        {

            ObservableCollection<Income> tempOC = bl.GetIncomesForUsers(user);
            ObservableCollection<Income> oc = new ObservableCollection<Income>();
            foreach (var item in tempOC)
            {
                oc.Add(new Income()
                {
                    Id = item.Id,
                    Date = item.Date,
                    Comment = item.Comment,
                    Amount = item.Amount,
                    UsersId = item.UsersId,
                    ActionTypeId = item.ActionTypeId
                });
            }

            return oc;
        }

        public ObservableCollection<Outcome> GetOutcomesForUsers(String user)
        {
            ObservableCollection<Outcome> tempOC = bl.GetOutcomesForUsers(user);
            ObservableCollection<Outcome> oc = new ObservableCollection<Outcome>();
            foreach (var item in tempOC)
            {
                oc.Add(new Outcome()
                {
                    Id = item.Id,
                    Date = item.Date,
                    Comment = item.Comment,
                    Amount = item.Amount,
                    UsersId = item.UsersId,
                    ActionTypeId = item.ActionTypeId
                });
            }

            return oc;
        }

        public int InsertIncome(Income income)
        {
            return bl.InsertIncome(income);
        }

        public int InsertOutcome(Outcome outcome)
        {
            return bl.InsertOutcome(outcome);
        }

        public void UpdateOutcome(Outcome outcome)
        {
            bl.UpdateOutcome(outcome);
        }

        public void UpdateIncome(Income income)
        {
            bl.UpdateIncome(income);
        }

        public void DeleteOutcome(int outcomeID)
        {
            bl.DeleteOutcome(outcomeID);
        }

        public void DeleteIncome(int incomeID)
        {
            bl.DeleteIncome(incomeID);
        }

        #region Reports
        public Double GetTotalIncomeForPeriod(ReportMessage reportMessage)
        {
            return bl.GetTotalIncomeForPeriod(reportMessage);

        }

        public Double GetTotalOutcomeForPeriod(ReportMessage reportMessage)
        {
            return bl.GetTotalOutcomeForPeriod(reportMessage);
        }

        public Double GetTotalBalanceForPeriod(ReportMessage reportMessage)
        {
            return bl.GetTotalBalanceForPeriod(reportMessage);
        }

        public IEnumerable<Report> GetIncomesBySections(ReportMessage reportMessage)
        {
            return bl.GetIncomesBySections(reportMessage);
        }

        public IEnumerable<Report> GetOutcomesBySections(ReportMessage reportMessage)
        {
            return bl.GetOutcomesBySections(reportMessage);
        }

        #endregion

    }
}
